﻿/*
Copyright 2010 Matías Fidemraizer (www.matiasfidemraizer.com).

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

using System;
using Comkarl.Architecture.Patterns.Factory;

namespace Comkarl.Architecture.Patterns.DomainModel
{
    /// <summary>
    /// Represents a factory of domains. 
    /// </summary>
    /// <typeparam name="TDomainObject">
    /// The type for the domain context.
    /// </typeparam>
    /// <typeparam name="TDomainContext">
    /// The type for the domain context in which objects are treated.
    /// </typeparam>
    /// <typeparam name="TDomainObjectIdentifierName">
    /// The type for the name for domain object's identifiers.
    /// </typeparam>
    /// <remarks>
    /// A domain context is initialized thanks to the type for a domain object because this model enforces the idea of
    /// working with strong entities instead of associated ones alone. 
    /// 
    /// That is if some domain context must be of 'A' domain object and the business domain is managing other kind of domain objects,
    /// there is no chance for having a mixed-domain context: any of other domain objects must be of the same business domain.
    /// </remarks>
    public class DomainContextFactory<TDomainContext, TDomainObjectIdentifierName, TDomainObject> : Factory<TDomainContext>
        where TDomainContext : DomainContext<TDomainObjectIdentifierName, TDomainObject>
        where TDomainObjectIdentifierName : IEquatable<TDomainObjectIdentifierName>
        where TDomainObject : DomainObject<TDomainObjectIdentifierName>, ICloneable
    {
        /// <summary>
        /// Creates a new context.
        /// </summary>
        /// <returns>
        /// A domain context.
        /// </returns>
        public static TDomainContext CreateContext()
        {
            return new DomainContextFactory<TDomainContext, TDomainObjectIdentifierName, TDomainObject>().Create<TDomainContext>();
        }
    }
}